Skip to content

Comments

Resource idempotency and other quality of life#33

Merged
AllanKoder merged 9 commits intomasterfrom
Resource-idempotency
Aug 29, 2025
Merged

Resource idempotency and other quality of life#33
AllanKoder merged 9 commits intomasterfrom
Resource-idempotency

Conversation

@AllanKoder
Copy link
Owner

No description provided.

Copilot AI review requested due to automatic review settings August 29, 2025 03:18
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements resource idempotency to prevent duplicate resource creation and includes several quality-of-life improvements. The main goal is to make the application more robust when handling resource submissions and improve user experience.

Key changes:

  • Added duplicate resource detection that returns existing resources instead of creating duplicates
  • Extracted resource creation logic into a dedicated service class for better maintainability
  • Added UI loading states and improved form submission handling

Reviewed Changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
app/Services/ComputerScienceResourceService.php New service class containing extracted resource creation and show page logic
app/Http/Controllers/ComputerScienceResourceController.php Refactored to use service class and handle duplicate resource exceptions
app/Exceptions/Resources/*.php Custom exceptions for resource validation and duplicate detection
tests/Feature/ComputerScienceResourceTest.php Added tests for idempotency, image cleanup, and model deletion behavior
tests/Feature/ResourceEditsTest.php Updated test to use unique image filenames and verify edit image cleanup
resources/js/Pages/Resources/Create.vue Added loading state management for form submission
resources/js/Pages/Resources/Form/TagsFields.vue Added disabled state for submit button during loading
resources/js/Components/Form/TagSelector.vue Improved dropdown positioning and removed backspace tag deletion
resources/js/Components/Resources/ResourceEdit/ResourceEditsFAQ.vue Fixed grammar error and added clarification about auto-upvoting
app/Http/Controllers/ResourceEditsController.php Changed from copy to move operation for image handling
app/Http/Controllers/UpvoteController.php Added TODO comment for refactoring
app/Http/Controllers/CommentController.php Reordered log parameters for consistency

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines 95 to 108
} catch (Throwable $e) {
DB::rollBack();
// Attempt to remove the uploaded image if it was stored
if (isset($path) && $path) {
try {
Storage::disk('public')->delete($path);
} catch (Throwable $removeEx) {
Log::warning('Failed to remove image after exception', [
'user_id' => Auth::id(),
'image_path' => $path,
'error' => $removeEx->getMessage(),
]);
}
}
Copy link

Copilot AI Aug 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable $path may not be defined in the catch block if an exception occurs before line 44. This will cause an 'undefined variable' error when checking isset($path).

Copilot uses AI. Check for mistakes.
$response->assertStatus(422); // Validation error

// The image should not exist in storage
Storage::disk('public')->assertMissing('resource/'.$formData['image_file']->hashName());
Copy link

Copilot AI Aug 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test is checking for the image at 'resource/'.$formData['image_file']->hashName() but the actual storage path uses store('resource', 'public') which may generate a different path format. The assertion should use the actual stored path or verify no files exist in the resource directory.

Suggested change
Storage::disk('public')->assertMissing('resource/'.$formData['image_file']->hashName());
$this->assertEmpty(Storage::disk('public')->allFiles('resource'), "Failed asserting that no image files exist in the 'resource' directory after failed resource creation.");

Copilot uses AI. Check for mistakes.
@AllanKoder AllanKoder merged commit ba84135 into master Aug 29, 2025
1 check passed
@AllanKoder AllanKoder deleted the Resource-idempotency branch August 29, 2025 03:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant